#include "sct/rtspserver/tssource.h"

namespace sct
{
CTsSource* CTsSource::createNew(UsageEnvironment& env, void* source)
{
	return new CTsSource(env, source);
}

CTsSource::CTsSource(UsageEnvironment& env, void* source):
		FramedSource(env),
		mSource((CStreamSource*)source),
		mStartReadTime(0),
		mReadTask(NULL)
{
	;
}

CTsSource::~CTsSource()
{
	if(mReadTask)
	{
		envir().taskScheduler().unscheduleDelayedTask(mReadTask);
	}
}

void CTsSource::tryToGetNextFrame(void* p)
{
	CTsSource* self = (CTsSource*)p;
	self->mReadTask = NULL;

	if(!self->isCurrentlyAwaitingData())
	{
		return;
	}

	int ret = 0;
	int64_t pts = 0;
	int ntrunc = 0;

	ret = self->mSource->getdata(self->fTo, self->fMaxSize, &pts, &ntrunc);
	if(ret <= 0)
	{
		///no data
		if(currentTime() - self->mStartReadTime > 3)
		{
			self->handleClosure();
		}
		else
		{
			self->mReadTask = self->envir().taskScheduler().scheduleDelayedTask(50000,
						tryToGetNextFrame, self);
		}
		return;
	}

	self->fFrameSize = ret;
	self->fNumTruncatedBytes = ntrunc;

	self->fPresentationTime.tv_sec = pts / 1000000;
	self->fPresentationTime.tv_usec = pts % 1000000;

	self->fDurationInMicroseconds = 0;

	self->nextTask() = self->envir().taskScheduler().scheduleDelayedTask(0,
			(TaskFunc*)FramedSource::afterGetting, self);
}

void CTsSource::doGetNextFrame()
{
	if(NULL == mReadTask)
	{
		mStartReadTime = currentTime();
		mReadTask = envir().taskScheduler().scheduleDelayedTask(0,
			tryToGetNextFrame, this);
	}
	else
	{
		SCT_LOGD();
	}
}

void CTsSource::doStopGettingFrames()
{
	if(mReadTask)
	{
		envir().taskScheduler().unscheduleDelayedTask(mReadTask);
	}
}
}//end namespace
